﻿namespace MvcXRepair.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Web.Mvc;
    using MvcXRepair.Models;
    using MvcXRepair.ViewModel;
    using MvcXRepairCustomer.Interfaces;
    using MvcXRepairCustomer.Services;
    using Newtonsoft.Json;
    using System.Linq;
    using XRepair.Models;
    using MvcXRepair.Controllers;
    using XRepair.WebCore.Authentication;
    using XRepair.Conventions.Enum;
    using MvcXRepairCustomer.CacheData;
    using System.Text;

    public class HomeController : BaseController
    {
        private ISymptomService _symptomService;
        private IServiceService _serviceService;
        private IOrderService _orderService;

        public HomeController()
        {
            _symptomService = new SymptomService();
            _serviceService = new ServiceService();
            _orderService = new OrderService();
        }

        [HttpGet]
        public ActionResult Index()
        {
            if (_userSession.IsAuthenticated && !_userSession.IsSessionExpired)
            {
                bool hasPendingOrder = Cache.HasPendingOrderWithKey(Session.SessionID);

                if (hasPendingOrder)
                {
                    // User has pending order, redirect to recovery page
                    return RedirectToAction("OrderRecovery");
                }
                else
                {
                    OrderViewModel pendingOrder = _orderService.GetPendingOrderViewModelByUsername(_userSession.Username);

                    if (pendingOrder != null)
                    {
                        Cache.SavePendingOrder(Session.SessionID, pendingOrder);
                        return RedirectToAction("OrderRecovery");
                    }
                }
            }

            ViewBag.BrandList = brandList;
            ViewBag.ModelList = modelList;

            var device = TempData["Device"] as Device;

            if (device != null)
            {
                TryValidateModel(device);
                return View(device);
            }

            return View();
        }

        [HttpPost]
        public ActionResult PlaceOrder(Device device)
        {
            if (ModelState.IsValid)
            {
                // Hardcode to get data
                // Remove 2 lines below when dropdown list of Brand and Model are ready.
                // So that the list of Symptom will be filtered by selected brand and model.

                //device.Model = "2";
                //device.Brand = "2";

                var jsonDeviceInf = JsonConvert.SerializeObject(device);
                ViewBag.JsonDeviceInf = jsonDeviceInf;
                var model = new OrderViewModel();

                Session["Device"] = device;

                var filterSymptomsByModelAndBrand = _symptomService.GetAllActiveSymptoms().Where(e => e.ModelID.Value.ToString() == device.Model && e.BrandID.Value.ToString() == device.Brand);

                List<SelectListItem> symptomList = filterSymptomsByModelAndBrand.Select(e => new SelectListItem { Text = e.Name, Value = e.ID.Value.ToString() }).ToList();

                ViewBag.SymptomList = symptomList;

                return View(model);
            }
            else
            {
                TempData["Device"] = device;
                return RedirectToAction("Index", "Home");
            }
        }

        [AllowAnonymous]
        [HttpGet]
        public ActionResult PlaceOrder()
        {
            OrderViewModel model = TempData["pendingOrder"] as OrderViewModel ?? new OrderViewModel();

            var jsonDeviceInf = JsonConvert.SerializeObject(model.Device);
            ViewBag.JsonDeviceInf = jsonDeviceInf;
            Device device = model.Device ?? Session["Device"] as Device;

            var filterSymptomsByModelAndBrand = _symptomService.GetAllActiveSymptoms().Where(e => e.ModelID.Value.ToString() == device.Model && e.BrandID.Value.ToString() == device.Brand);

            List<SelectListItem> symptomList = filterSymptomsByModelAndBrand.Select(e => new SelectListItem { Text = e.Name, Value = e.ID.Value.ToString() }).ToList();

            ViewBag.SymptomList = symptomList;

            return View(model);
        }

        //[xRepairAdminAuthorize(RoleID = UserPermission.NormalUser)]
        [AllowAnonymous]
        [HttpPost]
        public ActionResult ProcessOrder(OrderViewModel model, string processMode)
        {
            switch (processMode)
            {
                case "1":
                    {
                        // Users click login
                        model.Device = Session["Device"] as Device;
                        Cache.SavePendingOrder(Session.SessionID, model);
                        return RedirectToAction("Login", "User");
                    }
                case "2":
                    {
                        // Users click register
                        // Save pending order to db for later recovery
                        model.Device = Session["Device"] as Device;
                        Cache.SavePendingOrder(Session.SessionID, model);
                        return RedirectToAction("Register", "User");                        
                    }
                case "0":
                    {
                        // Users already login & click submit order
                        StringBuilder symptomIDs = new StringBuilder();
                        StringBuilder symptomNames = new StringBuilder();                       
                        var orderList = new Order();

                        orderList.BillingAddress = model.Address.BillingAddress;
                        orderList.ShippingAddress = model.Address.ShippingAddress;
                        orderList.CreatedBy = _userSession.Username;
                        orderList.CustomerID = _userSession.UserID;
                        orderList.CityID = Convert.ToInt32(model.Address.City);
                        orderList.StateID = Convert.ToInt32(model.Address.State);
                        orderList.ZipCode = model.Address.ZipCode;
                        orderList.CreatedAt = DateTime.Now;
                        model.Device = Session["Device"] as Device;

                        int?[] selectedSymptomIds = model.SelectedSymptoms.SymptomId;
                        string[] selectedSymptomNames = model.SelectedSymptoms.SymptomDescription;

                        foreach (int symptomID in selectedSymptomIds)
                        {
                            symptomIDs.AppendFormat("@{0}", symptomID);
                            //symptomListID = symptomListID + "@" + symptomID;
                        }

                        foreach (string symptomName in selectedSymptomNames)
                        {
                            symptomNames.AppendFormat("@{0}", symptomName);
                        }

                        orderList.SymptomIDList = symptomIDs.ToString();
                        orderList.CustomerDescriptionList = symptomNames.ToString();

                        bool succeed = _orderService.AddNewOrder(orderList);
                        if (succeed)
                        {
                            return View();
                        }
                        
                        return RedirectToAction("ErrorOnProcessing", "Error");
                    }
                default:
                    return RedirectToAction("ErrorOnProcessing", "Error");
            }
        }

        // Serve Ajax Requests
        public string CalculateOrderExpense(string[] selectedSymptomIds)
        {
            var filterServiceList = _serviceService.GetAllActiveServices().Where(e => selectedSymptomIds.Contains(e.SymptomTypeID.ToString()));
            var pricingDataList = new List<object>();

            if (filterServiceList != null && filterServiceList.Count() > 0)
            {
                pricingDataList = filterServiceList.Select(e => new { Des = e.ServiceDescription, LaborCost = e.LaborCost, DiscountLabor = e.DiscountLabor, PartCost = e.PartCost, DiscountPart = e.DiscountPart, Total = (e.LaborCost + e.DiscountLabor + e.PartCost + e.DiscountPart) }).ToList<object>();

                if (pricingDataList == null || pricingDataList.Count == 0)
                {
                    pricingDataList.Add(new { Des = "Please select device issue", LaborCost = "0", DiscountLabor = "0", PartCost = "0", DiscountPart = "0", Total = "0" });
                }
            }
            else
            {
                pricingDataList.Add(new { Des = "Cannot get pricing detail at the moment!", LaborCost = "0", DiscountLabor = "0", PartCost = "0", DiscountPart = "0", Total = "0" });
            }

            pricingDataList.Add(new { IsAuthenticated = _userSession.IsAuthenticated });

            var pricingJson = JsonConvert.SerializeObject(pricingDataList);
            return pricingJson;
        }

        public ActionResult OrderRecovery()
        {
            return View();
        }

        public ActionResult RecoverPendingOrder()
        {
            var pendingOrder = Cache.WithdrawPendingOrder(Session.SessionID) as OrderViewModel;

            if (pendingOrder != null)
            {
                TempData["pendingOrder"] = pendingOrder;
                return RedirectToAction("PlaceOrder");
            }

            return View("Index");
        }

        #region Dummy Data

        private Dictionary<int, object> pricingDict = new Dictionary<int, object> 
        { 
            {0, new {Des="Fix Device's Adaptor", LaborCost ="5.05", DiscountLabor = "0.00", PartCost="10.43", DiscountPart="0.50", Total="15.93"}},    
            {1, new {Des="Fix Device's Screen", LaborCost ="4.15", DiscountLabor = "0.50", PartCost="9.43", DiscountPart="0.50", Total="12.58"}},
            {2, new {Des="Fix Device's Camera", LaborCost ="20.15", DiscountLabor = "0.83", PartCost="30.43", DiscountPart="0.20", Total="49.55"}},

            {99, new {Des="Please select device issue", LaborCost ="0", DiscountLabor = "0", PartCost="0", DiscountPart="0", Total="0"}}
        };

        private List<SelectListItem> brandList = new List<SelectListItem> 
                    { 
                        new SelectListItem{Text="- Select brand -", Value = string.Empty},
                        new SelectListItem{Text="Apple", Value = "Apple"},
                        new SelectListItem{Text="Samsung", Value = "Samsung"},
                        new SelectListItem{Text="LG", Value = "LG"},        
                    };

        private List<SelectListItem> modelList = new List<SelectListItem>
            {
                new SelectListItem{Text="- Select model -", Value=string.Empty},
                new SelectListItem{Text="Dummy model #1", Value="Dummy model #1"},
                new SelectListItem{Text="Dummy model #2", Value="Dummy model #2"}
            };
    }

        #endregion
}
